HighBandwidthDecode.py

High-Bandwidth Lossless Compression

It shows how to decode lossless compression stream from the camera into raw data via high-bandwidth lossless compression related algorithm.

1 # -- coding: utf-8 --
2 
3 import sys
4 import ctypes
5 import platform
6 import os
7 from ctypes import *
8 
9 # Compatible with different operating systems to load DDL
10 currentsystem = platform.system()
11 if currentsystem == 'Windows':
12  sys.path.append(os.path.join(os.getenv('MVCAM_COMMON_RUNENV'), "Samples", "Python", "MvImport"))
13 else:
14  sys.path.append(os.path.join("..", "..", "MvImport"))
15 from MvCameraControl_class import *
16 
17 # Compatible with input processing of Python 2.X and 3.X
18 if sys.version_info[0] < 3:
19  # Python 2.x
20  input_func = raw_input
21 else:
22  # Python 3.x
23  input_func = input
24 
25 # Decoding Characters
26 def decoding_char(ctypes_char_array):
27  """
28  Safely decode a string from a ctypes character array.
29  Compatible with Python 2.x and 3.x, as well as 32-bit and 64-bit environments.
30  """
31  byte_str = memoryview(ctypes_char_array).tobytes()
32 
33  # Truncate at the first null character
34  null_index = byte_str.find(b'\x00')
35  if null_index != -1:
36  byte_str = byte_str[:null_index]
37 
38  # Attempt to decode using multiple encodings
39  for encoding in ['gbk', 'utf-8', 'latin-1']:
40  try:
41  return byte_str.decode(encoding)
42  except UnicodeDecodeError:
43  continue
44 
45  # If all encodings fail, use a replacement strategy
46  return byte_str.decode('latin-1', errors='replace')
47 
48 
49 
50 if __name__ == "__main__":
51  try:
52  # Initialize SDK resources
53  MvCamera.MV_CC_Initialize()
54 
55  SDKVersion = MvCamera.MV_CC_GetSDKVersion()
56  print ("SDKVersion[0x%x]" % SDKVersion)
57 
58  deviceList = MV_CC_DEVICE_INFO_LIST()
59  tlayerType = (MV_GIGE_DEVICE | MV_USB_DEVICE | MV_GENTL_CAMERALINK_DEVICE
60  | MV_GENTL_CXP_DEVICE | MV_GENTL_XOF_DEVICE)
61 
62  # Enumerate devices
63  ret = MvCamera.MV_CC_EnumDevices(tlayerType, deviceList)
64  if ret != 0:
65  print ("enum devices fail! ret[0x%x]" % ret)
66  sys.exit()
67 
68  if deviceList.nDeviceNum == 0:
69  print ("find no device!")
70  sys.exit()
71 
72  print ("Find %d devices!" % deviceList.nDeviceNum)
73 
74  for i in range(0, deviceList.nDeviceNum):
75  mvcc_dev_info = cast(deviceList.pDeviceInfo[i], POINTER(MV_CC_DEVICE_INFO)).contents
76  if mvcc_dev_info.nTLayerType == MV_GIGE_DEVICE or mvcc_dev_info.nTLayerType == MV_GENTL_GIGE_DEVICE:
77  print ("\ngige device: [%d]" % i)
78  strModeName = decoding_char(mvcc_dev_info.SpecialInfo.stGigEInfo.chModelName)
79  print ("device model name: %s" % strModeName)
80  strSerialNumber = decoding_char(mvcc_dev_info.SpecialInfo.stGigEInfo.chSerialNumber)
81  print("device serial number: %s" % strSerialNumber)
82  nip1 = ((mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0xff000000) >> 24)
83  nip2 = ((mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0x00ff0000) >> 16)
84  nip3 = ((mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0x0000ff00) >> 8)
85  nip4 = (mvcc_dev_info.SpecialInfo.stGigEInfo.nCurrentIp & 0x000000ff)
86  print ("current ip: %d.%d.%d.%d\n" % (nip1, nip2, nip3, nip4))
87  elif mvcc_dev_info.nTLayerType == MV_USB_DEVICE:
88  print ("\nu3v device: [%d]" % i)
89  strModeName = decoding_char(mvcc_dev_info.SpecialInfo.stUsb3VInfo.chModelName)
90  print ("device model name: %s" % strModeName)
91 
92  strSerialNumber = decoding_char(mvcc_dev_info.SpecialInfo.stUsb3VInfo.chSerialNumber)
93  print ("device serial number: %s" % strSerialNumber)
94  elif mvcc_dev_info.nTLayerType == MV_GENTL_CAMERALINK_DEVICE:
95  print ("\nCML device: [%d]" % i)
96  strModeName = decoding_char(mvcc_dev_info.SpecialInfo.stCMLInfo.chModelName)
97  print ("device model name: %s" % strModeName)
98 
99  strSerialNumber = decoding_char(mvcc_dev_info.SpecialInfo.stCMLInfo.chSerialNumber)
100  print ("device serial number: %s" % strSerialNumber)
101  elif mvcc_dev_info.nTLayerType == MV_GENTL_CXP_DEVICE:
102  print ("\nCXP device: [%d]" % i)
103  strModeName = decoding_char(mvcc_dev_info.SpecialInfo.stCXPInfo.chModelName)
104  print ("device model name: %s" % strModeName)
105 
106  strSerialNumber = decoding_char(mvcc_dev_info.SpecialInfo.stCXPInfo.chSerialNumber)
107  print ("device serial number: %s" % strSerialNumber)
108  elif mvcc_dev_info.nTLayerType == MV_GENTL_XOF_DEVICE:
109  print ("\nXoF device: [%d]" % i)
110  strModeName = decoding_char(mvcc_dev_info.SpecialInfo.stXoFInfo.chModelName)
111  print ("device model name: %s" % strModeName)
112 
113  strSerialNumber = decoding_char(mvcc_dev_info.SpecialInfo.stXoFInfo.chSerialNumber)
114  print ("device serial number: %s" % strSerialNumber)
115 
116  nConnectionNum = input_func("please input the number of the device to connect:")
117 
118  if int(nConnectionNum) >= deviceList.nDeviceNum:
119  print ("intput error!")
120  sys.exit()
121 
122  # Create the camera instance
123  cam = MvCamera()
124 
125  # Select a device, and create a handle
126  stDeviceList = cast(deviceList.pDeviceInfo[int(nConnectionNum)], POINTER(MV_CC_DEVICE_INFO)).contents
127 
128  ret = cam.MV_CC_CreateHandle(stDeviceList)
129  if ret != 0:
130  raise Exception ("create handle fail! ret[0x%x]" % ret)
131 
132  # Turn on the device
133  ret = cam.MV_CC_OpenDevice(MV_ACCESS_Exclusive, 0)
134  if ret != 0:
135  raise Exception ("open device fail! ret[0x%x]" % ret)
136 
137  # Get optimal packet size (only supported by GigE devices)
138  if stDeviceList.nTLayerType == MV_GIGE_DEVICE or stDeviceList.nTLayerType == MV_GENTL_GIGE_DEVICE:
139  nPacketSize = cam.MV_CC_GetOptimalPacketSize()
140  if int(nPacketSize) > 0:
141  ret = cam.MV_CC_SetIntValue("GevSCPSPacketSize",nPacketSize)
142  if ret != 0:
143  print ("Warning: Set Packet Size fail! ret[0x%x]" % ret)
144  else:
145  print ("Warning: Get Packet Size fail! ret[0x%x]" % nPacketSize)
146 
147  # Set trigger mode to off
148  ret = cam.MV_CC_SetEnumValue("TriggerMode", MV_TRIGGER_MODE_OFF)
149  if ret != 0:
150  raise Exception ("set trigger mode fail! ret[0x%x]" % ret)
151 
152  # Get packet size
153  nDevPayloadSize = c_uint64()
154  nMemAlignment = c_uint()
155  ret = cam.MV_CC_GetPayloadSize(nDevPayloadSize, nMemAlignment)
156  if 0 != ret:
157  raise Exception ("Get PayloadSize fail! ret[0x%x]" % ret)
158  nPayloadSize = nDevPayloadSize.value
159 
160  # Start grabbing images
161  ret = cam.MV_CC_StartGrabbing()
162  if ret != 0:
163  raise Exception ("start grabbing fail! ret[0x%x]" % ret)
164 
165  nImageNum = 10
166  stOutFrame = MV_FRAME_OUT()
167  stDecodeParam = MV_CC_HB_DECODE_PARAM()
168  memset(byref(stOutFrame), 0, sizeof(stOutFrame))
169  for i in range(0, nImageNum):
170  ret = cam.MV_CC_GetImageBuffer(stOutFrame, 1000)
171  if None != stOutFrame.pBufAddr and 0 == ret:
172  print("get one frame: Width[%d], Height[%d], nFrameNum[%d]" % (
173  stOutFrame.stFrameInfo.nWidth, stOutFrame.stFrameInfo.nHeight, stOutFrame.stFrameInfo.nFrameNum))
174 
175  stDecodeParam.pSrcBuf = stOutFrame.pBufAddr
176  stDecodeParam.nSrcLen = stOutFrame.stFrameInfo.nFrameLen
177  stDecodeParam.pDstBuf = (c_ubyte * nPayloadSize)()
178  stDecodeParam.nDstBufSize = nPayloadSize
179  ret = cam.MV_CC_HBDecode(stDecodeParam)
180  if ret != 0:
181  cam.MV_CC_FreeImageBuffer(stOutFrame)
182  raise Exception("HB Decode fail! ret[0x%x]" % ret)
183  else:
184  print("Decode succeed!")
185 
186  # Save images after decoding
187  file_path = "Image_w%d_h%d_fn%d.bmp" %(stDecodeParam.nWidth,stDecodeParam.nHeight, stOutFrame.stFrameInfo.nFrameNum)
188  c_file_path = file_path.encode('ascii')
189  stSaveParam = MV_SAVE_IMAGE_TO_FILE_PARAM_EX()
190  stSaveParam.enPixelType = stDecodeParam.enDstPixelType # Pixel format after decoding
191  stSaveParam.nWidth = stDecodeParam.nWidth # Width after decoding
192  stSaveParam.nHeight = stDecodeParam.nHeight # Height after decoding
193  stSaveParam.nDataLen = stDecodeParam.nDstBufLen # Buffer length after decoding
194  stSaveParam.pData = stDecodeParam.pDstBuf # Data after decoding
195  stSaveParam.enImageType = MV_Image_Bmp # The image format for saving
196  stSaveParam.pcImagePath = ctypes.create_string_buffer(c_file_path)
197  stSaveParam.iMethodValue = 1
198  stSaveParam.nQuality = 80 # ch: JPG: (50,99], invalid in other format
199  ret = cam.MV_CC_SaveImageToFileEx(stSaveParam)
200  if ret != 0:
201  cam.MV_CC_FreeImageBuffer(stOutFrame)
202  raise Exception("save image fail! ret[0x%x]" % ret)
203  else:
204  cam.MV_CC_FreeImageBuffer(stOutFrame)
205  print("save image success")
206  else:
207  print("no data[0x%x]" % ret)
208 
209  print ("press Enter key to stop grabbing.")
210  input_func()
211 
212  # Stop grabbing images
213  ret = cam.MV_CC_StopGrabbing()
214  if ret != 0:
215  raise Exception ("stop grabbing fail! ret[0x%x]" % ret)
216 
217 
218  # Turn off the device
219  ret = cam.MV_CC_CloseDevice()
220  if ret != 0:
221  raise Exception ("close deivce fail! ret[0x%x]" % ret)
222 
223  # Destroy the handle
224  cam.MV_CC_DestroyHandle()
225  except Exception as e:
226  print(e)
227  cam.MV_CC_CloseDevice()
228  cam.MV_CC_DestroyHandle()
229  finally:
230  # Release SDK resources
231  MvCamera.MV_CC_Finalize()